<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML标题</title>
    <link href="https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            min-height: 100vh;
            background: linear-gradient(135deg, #ffcce6, #c2e9fb, #e0f7fa);
            font-family: 'ZCOOL XiaoWei', serif;
            color: #333;
            position: relative;
            overflow-x: hidden;
            padding: 2rem;
            display: flex;
            justify-content: center;
            align-items: center;
            background-image:url('https://iknow-pic.cdn.bcebos.com/d000baa1cd11728b09d0dfbcdafcc3cec2fd2caa');//可自行替换背景图片
            background-size: cover;
            background-position: center;
            background-color: rgba(255,255,255,0.6);
            opacity:0.95
        }
        
        .container {
            position: relative;
            width: 90%;
            max-width: 800px;
            background: rgba(255, 255, 255, 0.85);
            border-radius: 20px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
            padding: 3rem;
            z-index: 10;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.2);
            overflow: hidden;
        }
        
        .floating-bg {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
        }
        
        .bg-element {
            position: absolute;
            background-size: contain;
            background-repeat: no-repeat;
            opacity: 0.08;
        }
        
        .dragon-boat {
            width: 100px;
            height: 80px;
            background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M8 44l8-4 8 4 8-4 8 4 8-4 8 4" stroke="%23d54d4d" stroke-width="2" fill="none"/><path d="M32 16v-4m-4 4l-2-2.5m8 2.5l2-2.5m-8 6l-4 4m12-4l4 4M2 32h60" stroke="%23d54d4d" stroke-width="2" fill="none"/><circle cx="32" cy="32" r="10" fill="%23ffba00"/><rect x="5" y="35" width="54" height="12" rx="2" fill="%23d54d4d"/><path d="M36 30c-2.76-1.31-4-2-4-4 0-1.73 2-4 4-4s4 2.27 4 4c0 2-1.24 2.69-4 4zm-8 0c2.76-1.31 4-2 4-4 0-1.73-2-4-4-4s-4 2.27-4 4c0 2 1.24 2.69 4 4z" fill="%23fff"/></svg>');
            top: 10%;
            right: 5%;
            animation: float 18s infinite ease-in-out;
        }
        
        .lotus {
            width: 60px;
            height: 60px;
            background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M32 12c0-2-1.34-4-3-4s-3 2-3 4v4c0 2 1.34 4 3 4s3-2 3-4v-4z" fill="%23f8bbd0"/><path d="M40 32c0-2-1.34-4-3-4s-3 2-3 4v4c0 2 1.34 4 3 4s3-2 3-4v-4zM24 32c0-2-1.34-4-3-4s-3 2-3 4v4c0 2 1.34 4 3 4s3-2 3-4v-4zM32 44c0-2-1.34-4-3-4s-3 2-3 4v4c0 2 1.34 4 3 4s3-2 3-4v-4z" fill="%23e91e63"/><path d="M42 50c0-2-1.34-4-3-4s-3 2-3 4v4c0 2 1.34 4 3 4s3-2 3-4v-4zM22 50c0-2-1.34-4-3-4s-3 2-3 4v4c0 2 1.34 4 3 4s3-2 3-4v-4z" fill="%23e91e63"/><path d="M32 23c-6.63 0-12 4.37-12 12s5.37 12 12 12 12-4.37 12-12-5.37-12-12-12z" fill="%23f48fb1"/></svg>');
            bottom: 20%;
            left: 8%;
            animation: float 12s infinite ease-in-out reverse;
        }
        
        .scroll {
            width: 80px;
            height: 80px;
            background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><path d="M54 50H10V14h44v36z" fill="%23fff" stroke="%23d54d4d" stroke-width="2"/><rect x="18" y="24" width="28" height="4" rx="1" fill="%23e0e0e0"/><rect x="18" y="32" width="28" height="4" rx="1" fill="%23e0e0e0"/><rect x="18" y="40" width="28" height="4" rx="1" fill="%23e0e0e0"/><path d="M18 20l10-4 10 4M38 20l10-4" stroke="%23d54d4d" stroke-width="2" fill="none"/></svg>');
            top: 15%;
            left: 15%;
            animation: float 20s infinite ease-in-out;
        }
        
        .header {
            text-align: center;
            margin-bottom: 2.5rem;
        }
        
        .title {
            font-family: 'Ma Shan Zheng', cursive;
            font-size: 3rem;
            color: #d54d4d;
            margin-bottom: 1rem;
            text-shadow: 3px 3px 0px rgba(0, 0, 0, 0.1);
            animation: fadeIn 1.5s ease-out, pulse 2s infinite 1.5s;
            position: relative;
        }
        
        .title::after {
            content: "";
            display: block;
            width: 150px;
            height: 4px;
            background: linear-gradient(90deg, transparent, #d54d4d, transparent);
            margin: 10px auto 0;
        }
        
        .date-info {
            font-size: 1.2rem;
            color: #7f5539;
            margin-bottom: 1rem;
        }
        
        .letter-content {
            line-height: 1.8;
            font-size: 1.1rem;
        }
        
        .blessing-group {
            margin: 1.5rem 0;
            padding: 0 1rem;
            font-family: "楷体","KaiTi",serif;
        }
        
        .blessing-line {
            margin: 0.8rem 0;
            padding: 0.6rem;
            background: rgba(245, 245, 245, 0.7);
            border-radius: 8px;
            box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
            position: relative;
            transition: all 0.3s ease;
            opacity: 0;
            animation: fadeInUp 0.5s forwards;
            text-align:center;
        }
        
        .blessing-line:nth-child(1) { animation-delay: 0.5s; }
        .blessing-line:nth-child(2) { animation-delay: 0.8s; }
        .blessing-line:nth-child(3) { animation-delay: 1.1s; }
        .blessing-line:nth-child(4) { animation-delay: 1.4s; }
        .blessing-line:nth-child(5) { animation-delay: 1.7s; }
        .blessing-line:nth-child(6) { animation-delay: 2.0s; }
        
        .blessing-line:hover {
            background: rgba(255, 246, 249, 0.9);
            transform: translateX(5px);
        }
        
        .special-note {
            background: rgba(248, 187, 208, 0.2);
            padding: 1.2rem;
            border-radius: 8px;
            margin: 2rem 0;
            border-left: 4px solid #f8bbd0;
            font-size: 12px;
            animation: fadeIn 1s ease-out 2.5s forwards;
            opacity: 0;
        }
        
        .signature {
            text-align: right;
            font-size: 1.4rem;
            font-weight: bold;
            color: #d54d4d;
            margin-top: 2rem;
            animation: fadeIn 1s ease-out 3s forwards;
            opacity: 0;
            font-family: '楷体';
        }
        

        .music-control {
            position: absolute;
            bottom: 2rem;
            right: 2rem;
            background: white;
            width: 50px;
            height: 50px;
            border-radius: 50%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
            transition: all 0.3s ease;
            z-index: 20;
        }
        
        .music-control:hover {
            transform: scale(1.1);
            background: #f8bbd0;
        }
        
        .music-icon {
            font-size: 1.5rem;
        }
        
        /* Animations */
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        
        @keyframes fadeInUp {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
        }
        
        @keyframes float {
            0% { transform: translateY(0) rotate(0deg); }
            50% { transform: translateY(-20px) rotate(5deg); }
            100% { transform: translateY(0) rotate(0deg); }
        }
        
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.02); }
            100% { transform: scale(1); }
        }
        
        /* Heart fall animation */
        .hearts-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 1;
            overflow: hidden;
        }
        
        .heart {
            position: absolute;
            width: 20px;
            height: 20px;
            background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23e91e63" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>');
            background-size: contain;
            background-repeat: no-repeat;
            top: -10%;
            animation: fall 8s linear infinite;
        }
        
        @keyframes fall {
            0% { transform: translateY(0) translateX(0) rotate(0); opacity: 1; }
            100% { transform: translateY(100vh) translateX(20px) rotate(360deg); opacity: 0; }
        }
    </style>
</head>
<body>
    <!-- Floating background elements -->
    <div class="floating-bg">
        <div class="bg-element dragon-boat"></div>
        <div class="bg-element lotus"></div>
        <div class="bg-element scroll"></div>
    </div>
    
    <!-- Falling hearts container -->
    <div class="hearts-container" id="hearts-container"></div>
    
    <!-- Main content -->
    <div class="container" style="text-align:center;">
        <div class="header"  style="text-align:center;align-items:center;justify-content:center">
            <h1 class="title">标题</h1>
            <div class="date-info">副标题</div>
            <canvas id="pinkboard" style="z-index:-100"></canvas>            
        </div>
        
        <div class="letter-content">
            <p style="animation: fadeInUp 1s ease-out;font-family:'黑体'">开场白。</p>
            
            <div class="blessing-group">
                <p class="blessing-line">祝福1。</p>
                <p class="blessing-line">祝福2。</p>
                <p class="blessing-line">祝福3。</p>
                <p class="blessing-line">祝福4。</p>
                <p class="blessing-line">祝福5。</p>
                <p class="blessing-line">祝福6。</p>
            </div>
            
            <p class="blessing-line" style="animation-delay: 2.3s;font-family:'华文行楷'">总结。</p>
            
            <div class="special-note">
                <p>特别的话</p>
            </div>
            <div class="signature">姓名</div>
            <div class="signature">日期</div>
        </div>
    </div>
    
    <!-- Music control -->
    <div class="music-control" id="music-control">
        <div class="music-icon">🎵</div>
    </div>
    
    <audio id="bgm" loop>
        <!-- 使用内联base64音频数据 -->
        <source src="https://www.kuwo.cn/play_detail/25177843?from=baidu" type="audio/mpeg">
    </audio>

    <script>
        // Create falling hearts
        function createHearts() {
            const container = document.getElementById('hearts-container');
            const numHearts = 30;
            
            for (let i = 0; i < numHearts; i++) {
                const heart = document.createElement('div');
                heart.classList.add('heart');
                heart.style.left = Math.random() * 100 + '%';
                heart.style.animationDuration = (Math.random() * 10 + 8) + 's';
                heart.style.animationDelay = Math.random() * 5 + 's';
                container.appendChild(heart);
            }
        }
        
        // Music control
        document.addEventListener('DOMContentLoaded', function() {
            createHearts();
            
            const musicControl = document.getElementById('music-control');
            const bgm = document.getElementById('bgm');
            let isPlaying = false;
            
            musicControl.addEventListener('click', function() {
                if (isPlaying) {
                    bgm.pause();
                    musicControl.innerHTML = '<div class="music-icon">🔇</div>';
                } else {
                    bgm.play().catch(e => console.log("音乐播放需要用户交互:", e));
                    musicControl.innerHTML = '<div class="music-icon">🎵</div>';
                }
                isPlaying = !isPlaying;
            });
        });

var settings = {
  particles: {
    length:   500,
    duration:   2,
    velocity: 100,
    effect: -0.75,
    size:      30,
  },
};

(function(){var b=0;var c=["ms","moz","webkit","o"];for(var a=0;a<c.length&&!window.requestAnimationFrame;++a){window.requestAnimationFrame=window[c[a]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[c[a]+"CancelAnimationFrame"]||window[c[a]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(h,e){var d=new Date().getTime();var f=Math.max(0,16-(d-b));var g=window.setTimeout(function(){h(d+f)},f);b=d+f;return g}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(d){clearTimeout(d)}}}());

var Point = (function() {
  function Point(x, y) {
    this.x = (typeof x !== 'undefined') ? x : 0;
    this.y = (typeof y !== 'undefined') ? y : 0;
  }
  Point.prototype.clone = function() {
    return new Point(this.x, this.y);
  };
  Point.prototype.length = function(length) {
    if (typeof length == 'undefined')
      return Math.sqrt(this.x * this.x + this.y * this.y);
    this.normalize();
    this.x *= length;
    this.y *= length;
    return this;
  };
  Point.prototype.normalize = function() {
    var length = this.length();
    this.x /= length;
    this.y /= length;
    return this;
  };
  return Point;
})();

var Particle = (function() {
  function Particle() {
    this.position = new Point();
    this.velocity = new Point();
    this.acceleration = new Point();
    this.age = 0;
  }
  Particle.prototype.initialize = function(x, y, dx, dy) {
    this.position.x = x;
    this.position.y = y;
    this.velocity.x = dx;
    this.velocity.y = dy;
    this.acceleration.x = dx * settings.particles.effect;
    this.acceleration.y = dy * settings.particles.effect;
    this.age = 0;
  };
  Particle.prototype.update = function(deltaTime) {
    this.position.x += this.velocity.x * deltaTime;
    this.position.y += this.velocity.y * deltaTime;
    this.velocity.x += this.acceleration.x * deltaTime;
    this.velocity.y += this.acceleration.y * deltaTime;
    this.age += deltaTime;
  };
  Particle.prototype.draw = function(context, image) {
    function ease(t) {
      return (--t) * t * t + 1;
    }
    var size = image.width * ease(this.age / settings.particles.duration);
    context.globalAlpha = 1 - this.age / settings.particles.duration;
    context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
  };
  return Particle;
})();

var ParticlePool = (function() {
  var particles,
      firstActive = 0,
      firstFree   = 0,
      duration    = settings.particles.duration;
  
  function ParticlePool(length) {
    particles = new Array(length);
    for (var i = 0; i < particles.length; i++)
      particles[i] = new Particle();
  }
  ParticlePool.prototype.add = function(x, y, dx, dy) {
    particles[firstFree].initialize(x, y, dx, dy);
    
    firstFree++;
    if (firstFree   == particles.length) firstFree   = 0;
    if (firstActive == firstFree       ) firstActive++;
    if (firstActive == particles.length) firstActive = 0;
  };
  ParticlePool.prototype.update = function(deltaTime) {
    var i;
    
    if (firstActive < firstFree) {
      for (i = firstActive; i < firstFree; i++)
        particles[i].update(deltaTime);
    }
    if (firstFree < firstActive) {
      for (i = firstActive; i < particles.length; i++)
        particles[i].update(deltaTime);
      for (i = 0; i < firstFree; i++)
        particles[i].update(deltaTime);
    }
    
    while (particles[firstActive].age >= duration && firstActive != firstFree) {
      firstActive++;
      if (firstActive == particles.length) firstActive = 0;
    }
    
    
  };
  ParticlePool.prototype.draw = function(context, image) {
    if (firstActive < firstFree) {
      for (i = firstActive; i < firstFree; i++)
        particles[i].draw(context, image);
    }
    if (firstFree < firstActive) {
      for (i = firstActive; i < particles.length; i++)
        particles[i].draw(context, image);
      for (i = 0; i < firstFree; i++)
        particles[i].draw(context, image);
    }
  };
  return ParticlePool;
})();

(function(canvas) {
  var context = canvas.getContext('2d'),
      particles = new ParticlePool(settings.particles.length),
      particleRate = settings.particles.length / settings.particles.duration, // particles/sec
      time;
  
  function pointOnHeart(t) {
    return new Point(
      160 * Math.pow(Math.sin(t), 3),
      130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
    );
  }
  
  var image = (function() {
    var canvas  = document.createElement('canvas'),
        context = canvas.getContext('2d');
    canvas.width  = settings.particles.size;
    canvas.height = settings.particles.size;
    function to(t) {
      var point = pointOnHeart(t);
      point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
      point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
      return point;
    }
    context.beginPath();
    var t = -Math.PI;
    var point = to(t);
    context.moveTo(point.x, point.y);
    while (t < Math.PI) {
      t += 0.01; 
      point = to(t);
      context.lineTo(point.x, point.y);
    }
    context.closePath();
    context.fillStyle = '#ea80b0';
    context.fill();
  
    var image = new Image();
    image.src = canvas.toDataURL();
    return image;
  })();
  
  function render() {
    requestAnimationFrame(render);
    
    var newTime   = new Date().getTime() / 1000,
        deltaTime = newTime - (time || newTime);
    time = newTime;
    
    context.clearRect(0, 0, canvas.width, canvas.height);
    
    var amount = particleRate * deltaTime;
    for (var i = 0; i < amount; i++) {
      var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
      var dir = pos.clone().length(settings.particles.velocity);
      particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
    }
    
    particles.update(deltaTime);
    particles.draw(context, image);
  }
  
  function onResize() {
    canvas.width  = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
  }
  window.onresize = onResize;
  
  setTimeout(function() {
    onResize();
    render();
  }, 10);
})(document.getElementById('pinkboard'));
    </script>
</body>
</html>